package dicebot.tools.dice;

import dicebot.tools.dice.Dice.DiceException;

public class DiceTool {

    public static String handle (String[] sub, String senderName) {
        String exp = "d20";
        int time = 1;
        if (sub.length == 1) {
            if (!sub[0].equals(".r")) {
                return null;
            }
        } else if (sub.length == 2) {
            if (!sub[0].equals(".r")) {
                return null;
            }
            exp = sub[1];
        } else if (sub.length == 3) {
            if (!sub[0].equals(".r")) {
                return null;
            }
            exp = sub[1];
            try {
                time = Integer.parseInt(sub[2]);
            } catch (Exception e) {
            }
            if (time < 0) {
                return "菲琳不需要掷骰子! ";
            } else if (time > (Math.random() * 10) + 10) {
                return "菲琳会很累的...";
            }
        }
        String result = senderName + "骰出了";
        if (time > 1) {
            result += ": \n";
        }
        for (int i = 0; i < time; i++) {
            String s = exp;
            DiceExpression expression = null;
            try {
                expression = buildFromString(exp);
            } catch (Exception e) {
                return "菲琳读不懂表达式! ";
            }
            if (expression == null) {
                return "菲琳读不懂表达式! ";
            }
            while (!(expression instanceof Number)) {
                try {
                    expression = expression.simplify();
                } catch (DiceException e) {
                    result += s + "\n";
                    result += e.getMessage();
                    return result;
                } catch (Exception e) {
                    return null;
                }
                s += "=" + expression;
            }
            result += s;
            if (i < time - 1) {
                result += "\n";
            }
        }
        return result;
    }

    public static DiceExpression buildFromString (String exp) {
        if (exp == null || exp.isEmpty()) {
            return null;
        }
        // find + and -
        int level;
        int i;
        char c = '\0';
        for (level = 0, i = 0; i < exp.length(); i++) {
            c = exp.charAt(i);
            if (c == '(') {
                level ++;
            } else if (c == ')') {
                level --;
            } else if (level == 0 && (c == '+' || c == '-')) {
                break;
            }
        }
        if (i < exp.length()) {
            String s1 = exp.substring(0, i);
            String s2 = exp.substring(i + 1, exp.length());
            if (s1.isEmpty()) {
                DiceExpression e = buildFromString(s2);
                if (c == '+') {
                    return e;
                } else if (c == '-') {
                    return new Negation(e);
                }
            }
            DiceExpression e1 = buildFromString(s1);
            DiceExpression e2 = buildFromString(s2);
            if (c == '+') {
                return new Add(e1, e2);
            } else if (c == '-') {
                return new Add(e1, new Negation(e2));
            }
        }

        // find *
        for (level = 0, i = 0; i < exp.length(); i++) {
            c = exp.charAt(i);
            if (c == '(') {
                level ++;
            } else if (c == ')') {
                level --;
            } else if (level == 0 && c == '*') {
                break;
            }
        }
        if (i < exp.length()) {
            String s1 = exp.substring(0, i);
            String s2 = exp.substring(i + 1, exp.length());
            DiceExpression e1 = buildFromString(s1);
            DiceExpression e2 = buildFromString(s2);
            return new Multiple(e1, e2);
        }
        
        // find d
        for (level = 0, i = 0; i < exp.length(); i++) {
            c = exp.charAt(i);
            if (c == '(') {
                level ++;
            } else if (c == ')') {
                level --;
            } else if (level == 0 && c == 'd') {
                break;
            }
        }
        if (i < exp.length()) {
            String s1 = exp.substring(0, i);
            if (s1.isEmpty()) {
                s1 = "1";
            }
            String s2 = exp.substring(i + 1, exp.length());
            DiceExpression e1 = buildFromString(s1);
            DiceExpression e2 = buildFromString(s2);
            return new Dice(e1, e2);
        }

        // delete ( and )
        if (exp.startsWith("(") && exp.endsWith(")")) {
            return buildFromString(exp.substring(1, exp.length() - 1));
        }

        // try number
        int value = Integer.parseInt(exp);
        return new Number(value);
    }
    
}
